package com.vicente.managerdemo.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.vicente.managerdemo.common.ResultBean;
import com.vicente.managerdemo.common.StringConst;
import com.vicente.managerdemo.dto.MenuQueryDto;
import com.vicente.managerdemo.dto.MenuVO;
import com.vicente.managerdemo.entity.Menu;
import com.vicente.managerdemo.mapper.MenuMapper;
import com.vicente.managerdemo.service.MenuService;
import com.vicente.managerdemo.utils.SmartBeanUtil;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 系统菜单信息表 服务实现类
 * </p>
 *
 * @author vicente
 * @since 2024-12-04
 */
@Service
public class MenuServiceImpl implements MenuService {

    @Resource
    private MenuMapper menuMapper;

    @Override
    public ResultBean saveMenu(Menu menu) {
        boolean menuNameUnique = this.checkMenuNameUnique(menu);
        if (menuNameUnique){
            if (menu.getMenuId() == null){
                menuMapper.insert(menu);
            }else {
                menuMapper.updateById(menu);
            }
            return ResultBean.getSuccess("保存菜单成功");
        }else {
            return ResultBean.getFail("该上级菜单下存在同名菜单！");
        }
    }

    @Override
    public ResultBean delete(Long menuId) {
        int delete = menuMapper.deleteById(menuId);
        if (delete > 0) {
            return ResultBean.getSuccess("删除成功");
        }
        return ResultBean.getFail("删除失败");
    }

    @Override
    public ResultBean listMenu(MenuQueryDto queryDto) {
        LambdaQueryWrapper<Menu> queryWrapper = new LambdaQueryWrapper<>();
        if (StringUtils.isNotEmpty(queryDto.getMenuName())){
            queryWrapper.like(Menu::getMenuName, queryDto.getMenuName());
        }
        queryWrapper.like(Menu::getParentId, queryDto.getParentId());
        return ResultBean.getSuccess(menuMapper.selectList(queryWrapper));
    }

    @Override
    public List<MenuVO> listTreeMenu(MenuQueryDto queryDto) {
        if (null == queryDto.getParentId()) {
            System.out.println("查询根目录菜单");
            queryDto.setParentId(NumberUtils.LONG_ZERO);
        }
        List<MenuVO> treeList = queryCategoryTree(queryDto);
        return treeList;
    }

    private List<MenuVO> queryCategoryTree(MenuQueryDto queryDto) {
        List<Menu> allMenuList = menuMapper.queryMenuByParam(queryDto);
        List<Menu> menuList = allMenuList.stream().filter(e -> e.getParentId().equals(queryDto.getParentId())).collect(Collectors.toList());
        List<MenuVO> treeList = SmartBeanUtil.copyList(menuList, MenuVO.class);
        treeList.forEach(e -> {
            e.setFullName(e.getMenuName());
        });
        // 递归设置子类
        this.queryAndSetSubMenu(treeList, allMenuList);
        return treeList;
    }

    /**
     * 递归查询设置类目子类
     * 从缓存查询子类
     *
     */
    private void queryAndSetSubMenu(List<MenuVO> treeList, List<Menu> allMenuList) {
        if (CollectionUtils.isEmpty(treeList)) {
            return;
        }
        List<Long> parentIdList = treeList.stream().map(MenuVO::getMenuId).collect(Collectors.toList());
        List<Menu> menuList = allMenuList.stream().filter(e -> parentIdList.contains(e.getParentId())).collect(Collectors.toList());
        Map<Long, List<Menu>> categorySubMap = menuList.stream().collect(Collectors.groupingBy(Menu::getParentId));
        treeList.forEach(e -> {
            List<Menu> childrenEntityList = categorySubMap.getOrDefault(e.getMenuId(), new ArrayList<>());
            List<MenuVO> childrenVOList = SmartBeanUtil.copyList(childrenEntityList, MenuVO.class);
            childrenVOList.forEach(item -> {
                item.setFullName(e.getFullName() + StringConst.SEPARATOR_SLASH + item.getMenuName());
            });
            // 递归查询
            this.queryAndSetSubMenu(childrenVOList, allMenuList);
            e.setChildren(childrenVOList);
        });
    }

    private boolean checkMenuNameUnique(Menu menu) {
        //可能新增或者更新菜单
        long menuId = StringUtils.isEmpty(String.valueOf(menu.getMenuId())) ? menu.getMenuId() : -1L;
        Menu entity = menuMapper.checkMenuNameUnique(menu.getMenuName(), menu.getParentId());
        return null == entity || entity.getMenuId() == menuId;
    }
}
